introduce shortname handles in all file formats.
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 19 Jan 2003 22:16:12 +0000 (22:16 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 19 Jan 2003 22:16:12 +0000 (22:16 +0000)
Make -s rename duplicate generated shortnames.

23 files changed:
gpsbabel/csv.c
gpsbabel/csv_util.c
gpsbabel/defs.h
gpsbabel/dna.c
gpsbabel/garmin.c
gpsbabel/gpsdrive.c
gpsbabel/gpsutil.c
gpsbabel/gpx.c
gpsbabel/holux.c
gpsbabel/magproto.c
gpsbabel/mapsend.c
gpsbabel/mapsource.c
gpsbabel/mkshort.c
gpsbabel/mxf.c
gpsbabel/ozi.c
gpsbabel/pcx.c
gpsbabel/psp.c
gpsbabel/tiger.c
gpsbabel/tmpro.c
gpsbabel/tpg.c
gpsbabel/waypt.c
gpsbabel/xcsv.c
gpsbabel/xmapwpt.c

index 3d6922fdecfbaedb8a476a29fb59d1f5643a3fcc..4302bb0794604c4675a6f8e415cea63ded0220d7 100644 (file)
@@ -26,6 +26,7 @@
 
 static FILE *file_in;
 static FILE *file_out;
+static void *mkshort_handle;
 static char *psn;
 
 #define MYNAME "CSV"
@@ -34,6 +35,8 @@ static void
 rd_init(const char *fname, const char *args)
 {
        file_in = fopen(fname, "r");
+       mkshort_handle = mkshort_new_handle();
+
        if (file_in == NULL) {
                fatal(MYNAME ": Cannot open %s for reading\n", fname);
        }
@@ -42,6 +45,7 @@ rd_init(const char *fname, const char *args)
 static void
 rd_deinit(void)
 {
+       mkshort_del_handle(mkshort_handle);
        fclose(file_in);
 }
 
@@ -49,6 +53,7 @@ static void
 wr_init(const char *fname, const char *args)
 {
        file_out = fopen(fname, "w");
+
        psn = get_option(args, "prefer_shortname");
 
        if (file_out == NULL) {
@@ -126,7 +131,7 @@ data_read(void)
                
                /* We'll make up our own shortname. */
                if (wpt_tmp->description) {
-                       wpt_tmp->shortname = mkshort(wpt_tmp->description);
+                       wpt_tmp->shortname = mkshort(mkshort_handle, wpt_tmp->description);
                        waypt_add(wpt_tmp);
                }
 
index cf5ee4a2fe958ecf84b71d389d1dc73377ebc320..3b5f2cecfc011300469436f1049199500095b71b 100644 (file)
@@ -34,6 +34,8 @@
 #define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0)
 #define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0)
 
+static void *mkshort_handle;
+
 /*********************************************************************/
 /* csv_stringclean() - remove any unwanted characters from string.   */
 /*                     returns copy of string.                       */
@@ -563,10 +565,10 @@ xcsv_waypt_pr(const waypoint *wpt)
     queue *elem, *tmp;
    
     if (wpt->shortname) {
-        anyname = xstrdup(wpt->shortname);
+        anyname = xstrdup(mkshort(mkshort_handle, wpt->shortname));
     } else
     if (wpt->description) {
-        anyname = xstrdup(wpt->description);
+        anyname = xstrdup(mkshort(mkshort_handle, wpt->description));
     } else
     if (wpt->notes) {
         anyname = xstrdup(wpt->notes);
@@ -574,13 +576,13 @@ xcsv_waypt_pr(const waypoint *wpt)
         anyname = xstrdup("");
         
     if ((anyname) && (global_opts.synthesize_shortnames)) {
-        anyname = mkshort(anyname);
+        anyname = mkshort(mkshort_handle, anyname);
     }
     
     if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
         if (wpt->description) {
             if (global_opts.synthesize_shortnames)
-                shortname = mkshort(wpt->description);
+                shortname = mkshort(mkshort_handle, wpt->description);
             else
                 shortname = csv_stringclean(wpt->description, xcsv_file.badchars);
         } else {
@@ -764,13 +766,13 @@ xcsv_data_write(void)
 {
     queue *elem, *tmp;
     ogue_t *ogp;
+    mkshort_handle = mkshort_new_handle();
 
     /* output prologue lines, if any. */
     QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) {
         ogp = (ogue_t *) elem;
         fprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter);
     }
-
     waypt_disp_all(xcsv_waypt_pr);
 
     /* output epilogue lines, if any. */
@@ -778,5 +780,6 @@ xcsv_data_write(void)
         ogp = (ogue_t *) elem;
         fprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter);
     }
+    mkshort_del_handle(mkshort_handle);
 }
 
index d7c6f318636231113849f544e16011129268a1f6..60a4aeb7f22230a78a9ecbbda72aa928b19c6f8b 100644 (file)
@@ -180,11 +180,16 @@ void route_add (waypoint *);
 void route_add_wpt(route_head *rte, waypoint *wpt);
 void route_add_head(route_head *rte);
 
-char *mkshort (const char *);
-void setshort_length(int n);
-void setshort_badchars(const char *);
-void setshort_mustupper(int n);
-void setshort_whitespace_ok(int n);
+/*
+ * All shortname functions take a shortname handle as the first arg.
+ * This is an opaque pointer.  Callers must not fondle the contents of it.
+ */
+char *mkshort (void *, const char *);
+void *mkshort_new_handle(void);
+void setshort_length(void *, int n);
+void setshort_badchars(void *, const char *);
+void setshort_mustupper(void *, int n);
+void setshort_whitespace_ok(void *, int n);
 
 typedef struct ff_vecs {
        ff_init rd_init;
index 54eb791bea4e1ae52e9ab64379137931532d159f..d10430c5e0eb3fc070f14249873891fb3f2713f3 100644 (file)
@@ -28,6 +28,7 @@
 
 static FILE *file_in;
 static FILE *file_out;
+static void *mkshort_handle;
 
 #define MYNAME "DNA"
 
@@ -35,6 +36,8 @@ static void
 rd_init(const char *fname, const char *args)
 {
        file_in = fopen(fname, "r");
+       mkshort_handle = mkshort_new_handle();
+
        if (file_in == NULL) {
                fatal(MYNAME ": Cannot open %s for reading\n", fname);
        }
@@ -43,6 +46,7 @@ rd_init(const char *fname, const char *args)
 static void
 rd_deinit(void)
 {
+       mkshort_del_handle(mkshort_handle);
        fclose(file_in);
 }
 
@@ -50,6 +54,7 @@ static void
 wr_init(const char *fname, const char *args)
 {
        file_out = fopen(fname, "w");
+
        if (file_out == NULL) {
                fatal(MYNAME ": Cannot open %s for writing\n", fname);
        }
@@ -111,7 +116,7 @@ data_read(void)
                wpt_tmp->creation_time = time(NULL);
                
                /* We'll make up our own shortname. */
-               wpt_tmp->shortname = mkshort(wpt_tmp->description);
+               wpt_tmp->shortname = mkshort(mkshort_handle, wpt_tmp->description);
                
                waypt_add(wpt_tmp);
 
index 2ef89bd3f1245481b9fdf8bfcf71f59b5854d96f..5fa38cb7293537c22fc6e6dfa8ebbc25de8ef49c 100644 (file)
 
 #define MYNAME "GARMIN" 
 static const char *portname;
+static void *mkshort_handle;
 
 static void
 rw_init(const char *fname, const char *opts)
 {
+       if (!mkshort_handle)
+               mkshort_handle = mkshort_new_handle();
+
        if (global_opts.debug_level > 0)  {
                GPS_Enable_Warning();
                GPS_Enable_User();
@@ -211,8 +215,8 @@ data_write(void)
                        break;
                        
        }
-       setshort_length(short_length);
-       setshort_mustupper(1);
+       setshort_length(mkshort_handle, short_length);
+       setshort_mustupper(mkshort_handle, 1);
        QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
                waypoint *wpt;
                char *ident;
@@ -238,7 +242,7 @@ data_write(void)
                if(wpt->notes) src = wpt->notes;
 
                ident = global_opts.synthesize_shortnames ? 
-                               mkshort(src) : 
+                               mkshort(mkshort_handle, src) : 
                                wpt->shortname;
                strncpy(way[i]->ident,  ident, sizeof(way[i]->ident));
                way[i]->ident[sizeof(way[i]->ident)-1] = 0;
index ef9fe2b5c51f511be528a1d165bd90c99d1a854f..3287e5d274206e9cb8bc04b84f9462aaf4e6b32f 100644 (file)
@@ -33,6 +33,8 @@
 
 static FILE *file_in;
 static FILE *file_out;
+static void *mkshort_wr_handle;
+static void *mkshort_rd_handle;
 
 #define MYNAME "GPSDRIVE"
 
@@ -75,6 +77,7 @@ data_read(void)
        int i;
        waypoint *wpt_tmp;
        int linecount = 0;
+       mkshort_rd_handle = mkshort_new_handle();
 
        do {
                linecount++;
@@ -117,7 +120,7 @@ data_read(void)
                
                /* We'll make up our own shortname. */
                if (wpt_tmp->description) {
-                       wpt_tmp->shortname = mkshort(wpt_tmp->description);
+                       wpt_tmp->shortname = mkshort(mkshort_rd_handle, wpt_tmp->description);
                        waypt_add(wpt_tmp);
                }
 
@@ -126,6 +129,7 @@ data_read(void)
        }
 
     } while (!feof(file_in));
+    mkshort_del_handle(mkshort_rd_handle);
 }
 
 static void
@@ -147,7 +151,7 @@ gpsdrive_waypt_pr(const waypoint *wpt)
            shortname = csv_stringclean(wpt->notes, ",\"");
 
        if ( shortname )
-               shortname = mkshort(shortname);
+               shortname = mkshort(mkshort_wr_handle, shortname);
 
        fprintf(file_out, "%s %08.5f %08.5f\n",
                shortname,
@@ -162,7 +166,10 @@ gpsdrive_waypt_pr(const waypoint *wpt)
 static void
 data_write(void)
 {
+       mkshort_wr_handle = mkshort_new_handle();
+
        waypt_disp_all(gpsdrive_waypt_pr);
+       mkshort_del_handle(mkshort_wr_handle);
 }
 
 ff_vecs_t gpsdrive_vecs = {
index 42fb4dbb9ed261bc0906d916665c63c98aff7920..4f7a86f807af2402e6da83ccecd29332e08618e2 100644 (file)
@@ -7,6 +7,7 @@
 
 static FILE *file_in;
 static FILE *file_out;
+static void *mkshort_handle;
 
 #define MYNAME "GPSUTIL"
 
@@ -32,12 +33,15 @@ wr_init(const char *fname, const char *args)
        if (file_out == NULL) {
                fatal(MYNAME ": Cannot open %s for writing\n", fname);
        }
+       mkshort_handle = mkshort_new_handle();
+
 }
 
 static void
 wr_deinit(void)
 {
        fclose(file_out);
+       mkshort_del_handle(mkshort_handle);
 }
 
 static void
@@ -89,7 +93,8 @@ gpsutil_disp(const waypoint *wpt)
 
        fprintf(file_out, "%-8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n",
                 global_opts.synthesize_shortnames ?
-                        mkshort(wpt->description) : wpt->shortname,
+                        mkshort(mkshort_handle, wpt->description) : 
+                       wpt->shortname,
                fabs(lat),
                lat < 0.0 ? 'S' : 'N',
                fabs(lon),
index 98af66274f336b57cc1e3c9d8a83f2427c215744..22a029273f381c2f38ee81bf661ccb5e7d35aeda 100644 (file)
@@ -51,6 +51,7 @@ static const char *gpx_creator;
 static waypoint *wpt_tmp;
 static FILE *fd;
 static FILE *ofd;
+static void *mkshort_handle;
 
 #define MYNAME "GPX"
 #define MY_CBUF 4096
@@ -155,7 +156,6 @@ start_something_else(const char *el, const char **attrv)
        const char **avp = attrv;
        char **avcp = NULL;
        int attr_count = 0;
-       
        xml_tag *new_tag;
        
        if ( !wpt_tmp ) {
@@ -532,6 +532,7 @@ gpx_rd_deinit(void)
 void
 gpx_wr_init(const char *fname, const char *args)
 {
+       mkshort_handle = mkshort_new_handle();
        ofd = fopen(fname, "w");
        if (ofd == NULL) {
                fatal(MYNAME ": open %s for writing\n", fname );
@@ -542,6 +543,7 @@ static void
 gpx_wr_deinit(void)
 {
        fclose(ofd);
+       mkshort_del_handle(mkshort_handle);
 }
 
 void
@@ -632,7 +634,7 @@ gpx_waypt_pr(const waypoint *waypointp)
 {
        char *tmp_ent;
        const char *oname = global_opts.synthesize_shortnames ?
-                                 mkshort(waypointp->description) : 
+                                 mkshort(mkshort_handle, waypointp->description) : 
                                  waypointp->shortname;
 
        fprintf(ofd, "<wpt lat=\"%lf\" lon=\"%lf\">\n",
@@ -724,7 +726,7 @@ void gpx_track_pr()
 void
 gpx_write(void)
 {
-       setshort_length(32);
+       setshort_length(mkshort_handle, 32);
 
        fprintf(ofd, "<?xml version=\"1.0\"?>\n");
        fprintf(ofd, "<gpx\n version=\"1.0\"\n");
index 42b8b303fa78a0d90d078266fd7b883eb96f180d..0218215510af5160e14e83593f146282c5dee95e 100644 (file)
@@ -34,6 +34,7 @@ History:
 
 static  FILE *file_in;
 static         unsigned char *HxWFile;
+static  void *mkshort_handle;
 static  char fOutname[256];
 
 
@@ -58,6 +59,8 @@ static void rd_deinit(void)
 static void
 wr_init(const char *fname, const char *args)
 {
+       mkshort_handle = mkshort_new_handle();
+
        HxWFile = xcalloc(GM100_WPO_FILE_SIZE, 1);
 
        strcpy (fOutname,fname);
@@ -69,6 +72,7 @@ wr_init(const char *fname, const char *args)
 
 static void wr_deinit(void)
 {   
+        mkshort_del_handle(mkshort_handle);
 
 }
 
@@ -156,8 +160,8 @@ char *mknshort (char *stIn,unsigned int sLen)
     if (stIn == NULL)
         return NULL;
 
-    setshort_length(sLen);
-    strcpy(strTmp,mkshort(stIn));      
+    setshort_length(mkshort_handle, sLen);
+    strcpy(strTmp,mkshort(mkshort_handle, stIn));      
 
     memset(strOut,' ', MAX_STRINGLEN);
     strncpy (strOut,strTmp,strlen(strTmp));
index 7b150ad073c24f54d8e735d67957a277398f2fc2..c2ca6377f2c2655532630103bfadd4f945356e4e 100644 (file)
@@ -38,6 +38,7 @@ static char * termread(char *ibuf, int size);
 static void termwrite(char *obuf, int size);
 static double mag2degrees(double mag_val);
 static void mag_readmsg(void);
+static void *mkshort_handle;
 
 typedef enum {
        mrs_handoff = 0,
@@ -330,16 +331,16 @@ mag_verparse(char *ibuf)
                case mm_gps315320:
                case mm_map410:
                        icon_mapping = gps315_icon_table;
-                       setshort_length(6);
-                       setshort_mustupper(1);
+                       setshort_length(mkshort_handle, 6);
+                       setshort_mustupper(mkshort_handle, 1);
                        mag_cleanse = m315_cleanse;
                        break;
                case mm_map330:
                case mm_meridian:
                case mm_sportrak:
                        icon_mapping = map330_icon_table;
-                       setshort_length(8);
-                       setshort_mustupper(0);
+                       setshort_length(mkshort_handle, 8);
+                       setshort_mustupper(mkshort_handle, 0);
                        mag_cleanse = m330_cleanse;
                        break;
                default:
@@ -714,6 +715,7 @@ mag_wr_init(const char *portname, const char *args)
        fstat(fileno(magfile_out), &sbuf);
        is_file = S_ISREG(sbuf.st_mode);
 #endif
+       mkshort_handle = mkshort_new_handle();
 
        if (is_file) {
                magfile_out = fopen(portname, "w+b");
@@ -1066,7 +1068,7 @@ mag_waypt_pr(const waypoint *waypointp)
        }
        isrc = waypointp->notes ? waypointp->notes : waypointp->description;
        owpt = global_opts.synthesize_shortnames ?
-                        mkshort(isrc) : waypointp->shortname,
+                        mkshort(mkshort_handle, isrc) : waypointp->shortname,
        odesc = isrc ? isrc : "";
        owpt = mag_cleanse(owpt);
        odesc = mag_cleanse(odesc);
@@ -1098,7 +1100,7 @@ mag_write(void)
         * Whitespace is actually legal, but since waypoint name length is
         * only 8 bytes, we'll conserve them.
         */
-       setshort_whitespace_ok(0);
+       setshort_whitespace_ok(mkshort_handle, 0);
        waypt_disp_all(mag_waypt_pr);
 }
 
index 3fdbe822480474837031ab7cc68406d46411108a..5644133be3f8d4d15619e2f1381cd388f3ab0e74 100644 (file)
@@ -26,6 +26,7 @@
 
 static FILE *mapsend_file_in;
 static FILE *mapsend_file_out;
+static void *mkshort_handle;
 
 static int endianness_tested;
 static int i_am_little_endian;
@@ -171,12 +172,14 @@ mapsend_wr_init(const char *fname, const char *args)
                fprintf(stderr, "Cannot open '%s' for writing\n", fname);
                exit(1);
        }
+       mkshort_handle = mkshort_new_handle();
 }
 
 static void
 mapsend_wr_deinit(void)
 {
        fclose(mapsend_file_out);
+       mkshort_del_handle(mkshort_handle);
 }
 
 static void
@@ -313,7 +316,8 @@ mapsend_waypt_pr(const waypoint *waypointp)
        double flat;
        static int cnt = 0;
        const char *sn = global_opts.synthesize_shortnames ? 
-               mkshort(waypointp->description) : waypointp->shortname;
+               mkshort(mkshort_handle, waypointp->description) :
+               waypointp->shortname;
 
        c = strlen(sn);
        fwrite(&c, 1, 1, mapsend_file_out);
index 1458c387a432a750ade87d2fd3c75df679b3efe1..d775efcfcc8c74a82a469832429a08d57db0855e 100644 (file)
@@ -27,6 +27,7 @@
 
 static FILE *mps_file_in;
 static FILE *mps_file_out;
+static void *mkshort_handle;
 
 #define MYNAME "MAPSOURCE" 
 
@@ -226,7 +227,7 @@ mps_waypt_pr(const waypoint *wpt)
        if(wpt->description) src = wpt->description;
        if(wpt->notes) src = wpt->notes;
        ident = global_opts.synthesize_shortnames ?
-                               mkshort(src) :
+                               mkshort(mkshort_handle, src) :
                                wpt->shortname;
 
        reclen = 87 + strlen(ident) + strlen(wpt->description);
@@ -264,13 +265,16 @@ void
 mps_write(void)
 {
        int short_length = 10;
+       mkshort_handle = mkshort_new_handle();
 
-       setshort_length(short_length);
-       setshort_whitespace_ok(0);
+       setshort_length(mkshort_handle, short_length);
+       setshort_whitespace_ok(mkshort_handle, 0);
 
        fwrite(mps_hdr, sizeof(mps_hdr), 1, mps_file_out);
        waypt_disp_all(mps_waypt_pr);
        fwrite(mps_ftr, sizeof(mps_ftr), 1, mps_file_out);
+       mkshort_del_handle(mkshort_handle);
+
 }
 
 ff_vecs_t mps_vecs = {
index e586af23658ae28da0f262a8e8fa1a4918e13e8c..dc77471cfdb77c76651b3e0201a53c5e1efaab93 100644 (file)
 static const char vowels[] = "aeiouAEIOU";
 
 #define DEFAULT_TARGET_LEN 8
-static unsigned int target_len = DEFAULT_TARGET_LEN;
-
 #define DEFAULT_BADCHARS "\"$.,'!-"
-static const char *badchars = DEFAULT_BADCHARS;
 
-static int mustupper = 0;
-static int whitespaceok = 1;
-static const char needmem[] = 
-       "mkshort: could not reallocate memory for string\n";
+/*
+ * Hash table tunings.   The reality is that our hash doesn't have to be 
+ * terribly complex; our strings are short (typically 8-20 bytes) and the
+ * string hash mixes things up enough that strcmp can generally bail on the
+ * first byte or two for a mismatch.  
+ */
+#define PRIME 37
+
+typedef struct {
+       int mustupper;
+       int whitespaceok;
+       unsigned int target_len;
+       char *badchars;
+       int must_uniq;
+       queue namelist[PRIME];
+       int depth[PRIME];
+} mkshort_handle;
+
+typedef struct {
+       queue list;
+       char *orig_shortname;
+       int conflictctr;
+} uniq_shortname;
+
+unsigned int hash_string(const char *key)
+{
+       unsigned int hash = 0;
+       while (*key) {
+               hash = ((hash<<5) ^ (hash>>27)) ^ *key++;
+       }
+       hash = hash % PRIME;
+       return hash;
+}
+
+void *
+mkshort_new_handle()
+{
+       int i;
+       mkshort_handle *h = xcalloc(sizeof *h, 1);
+
+       for (i = 0; i < PRIME; i++)
+               QUEUE_INIT(&h->namelist[i]);
+
+       h->whitespaceok = 1;
+       h->badchars = DEFAULT_BADCHARS;
+       h->target_len = DEFAULT_TARGET_LEN;
+       h->must_uniq=1;
+
+       return h;
+}
+
+char *
+mkshort_add_to_list(mkshort_handle *h, char *name)
+{
+       queue *e, *t;
+       int hash;
+       uniq_shortname *s = xmalloc(sizeof (uniq_shortname));
+       s->orig_shortname = strdup(name);
+       hash = hash_string(name);
+
+       QUEUE_FOR_EACH(&h->namelist[hash], e, t) {
+               uniq_shortname *z = (uniq_shortname *) e;
+
+               if (0 == strcmp(z->orig_shortname, name)) {
+                       int l = strlen(name);
+                       int dl;
+                       char tbuf[10];
+
+                       z->conflictctr++;
+                       dl = sprintf(tbuf, ".%d", z->conflictctr);
+                       strcpy(&name[l-dl], tbuf);
+                       break;
+               }
+       }
+       ENQUEUE_TAIL(&h->namelist[hash], &s->list);
+       h->depth[hash]++;
+       return name;
+}
+
+void *
+mkshort_is_unique()
+{
+}
+
+void *
+mkshort_del_handle(void *h)
+{
+       mkshort_handle *hdr = h;
+       int i;
+
+       if (hdr) {
+               for (i = 0; i < PRIME; i++) {
+                       queue *e, *t, *z;
+                       QUEUE_FOR_EACH(&hdr->namelist[i], e, t) {
+                               uniq_shortname *s = e;
+                               dequeue(e);
+                               free(s->orig_shortname);
+                               free(s);
+                       }
+               }
+               free(hdr);
+       }
+}
 
 /*
  * This is the stuff that makes me ashamed to be a C programmer...
@@ -50,19 +146,21 @@ delete_last_vowel(int start, char *istring, int *replaced)
  * strings returned by mkshort().  0 resets to default.
  */
 void
-setshort_length(int l)
+setshort_length(void *h, int l)
 {
+       mkshort_handle *hdl = h;
        if (l == 0) {
-               target_len = DEFAULT_TARGET_LEN;
+               hdl->target_len = DEFAULT_TARGET_LEN;
        } else {
-               target_len = l;
+               hdl->target_len = l;
        }
 }
 
 void
-setshort_whitespace_ok(int l)
+setshort_whitespace_ok(void *h, int l)
 {
-       whitespaceok = l;
+       mkshort_handle *hdl = h;
+       hdl->whitespaceok = l;
 }
 
 /*
@@ -71,23 +169,25 @@ setshort_whitespace_ok(int l)
  * resets to default.
  */
 void
-setshort_badchars(const char *s)
+setshort_badchars(void *h, const char *s)
 {
+       mkshort_handle *hdl = h;
        if (s == NULL) {
-               badchars = DEFAULT_BADCHARS;
+               hdl->badchars = DEFAULT_BADCHARS;
        } else {
-               badchars = xstrdup(s);
+               hdl->badchars = xstrdup(s);
        }
 }
 
 void
-setshort_mustupper(int i)
+setshort_mustupper(void *h, int i)
 {
-       mustupper = i;
+       mkshort_handle *hdl = h;
+       hdl->mustupper = i;
 }
 
 char *
-mkshort(const char *istring)
+mkshort(void *h, const char *istring)
 {
        char *ostring = xstrdup(istring);
        char *nstring;
@@ -95,11 +195,12 @@ mkshort(const char *istring)
        char *cp;
        char *np;
        int i, l, nlen, replaced;
+       mkshort_handle *hdl = h;
 
        /* 
         * Whack leading "[Tt]he",
         */
-       if (( strlen(ostring) > target_len + 4) && 
+       if (( strlen(ostring) > hdl->target_len + 4) && 
            (strncmp(ostring, "The ", 4) == 0 || 
            strncmp(ostring, "the ", 4) == 0)) {
                nstring = xstrdup(ostring + 4);
@@ -123,7 +224,7 @@ mkshort(const char *istring)
        free(ostring);
        ostring = nstring;
 
-       if (!whitespaceok) {
+       if (!hdl->whitespaceok) {
                /* 
                 * Eliminate Whitespace 
                 */
@@ -132,7 +233,7 @@ mkshort(const char *istring)
                cp = ostring;
                for (i=0;i<l;i++) {
                        if (!isspace(tstring[i])) {
-                               if (mustupper) {
+                               if (hdl->mustupper) {
                                        tstring[i] = toupper(tstring[i]);
                                }
                                *cp++ = tstring[i];
@@ -150,7 +251,7 @@ mkshort(const char *istring)
        l = strlen (tstring);
        cp = ostring;
        for (i=0;i<l;i++) {
-               if (strchr(badchars, tstring[i]) || !isascii(tstring[i]))
+               if (strchr(hdl->badchars, tstring[i]) || !isascii(tstring[i]))
                        continue;
                *cp++ = tstring[i];
        }
@@ -175,7 +276,7 @@ mkshort(const char *istring)
         * them.  If we run out of string, give up.
         */
        replaced = 1;
-       while (replaced && strlen(ostring) > target_len) {
+       while (replaced && strlen(ostring) > hdl->target_len) {
                ostring = delete_last_vowel(2, ostring, &replaced);
        }
        
@@ -197,9 +298,15 @@ mkshort(const char *istring)
         * Now brutally truncate the resulting string, preserve trailing 
         * numeric data.
         */
-       if ((/*i = */strlen(ostring)) > target_len) {
-               strcpy(&ostring[target_len] - strlen(np), np);
+       if ((/*i = */strlen(ostring)) > hdl->target_len) {
+               strcpy(&ostring[hdl->target_len] - strlen(np), np);
        }
+
+
+       if (hdl->must_uniq) {
+               return mkshort_add_to_list(hdl, ostring);
+       }
+
        return ostring;
 }
 
index 6a90375b5971489f2c07ea408fddb604a64df562..d7675b56d1b5d6bed799aca68926180b6f4b6ce8 100644 (file)
@@ -33,6 +33,8 @@
 
 #define MYNAME "MXF"
 
+static void *mkshort_handle;
+
 static void
 mxf_set_style()
 {
@@ -65,9 +67,9 @@ mxf_set_style()
 
     /* set up mkshort */
     if (global_opts.synthesize_shortnames) {
-        setshort_length(32);
-        setshort_whitespace_ok(0);
-        setshort_badchars(xcsv_file.badchars);
+        setshort_length(mkshort_handle, 32);
+        setshort_whitespace_ok(mkshort_handle, 0);
+        setshort_badchars(mkshort_handle, xcsv_file.badchars);
     }
 }
 
@@ -86,6 +88,8 @@ mxf_rd_init(const char *fname, const char *args)
 static void
 mxf_wr_init(const char *fname, const char *args)
 {
+    mkshort_handle = mkshort_new_handle();
+
     mxf_set_style();
 
     xcsv_file.xcsvfp = fopen(fname, "w");
index 9d3e8bc5b9e9b5d80b02aec751a457479a98b1f2..550a99fb997d64626f3afbb1e02a92b9dfc1b3e4 100644 (file)
@@ -30,6 +30,9 @@
 
 #define MYNAME "OZI"
 
+static void *mkshort_handle;
+
+
 static void
 ozi_set_style()
 {
@@ -78,9 +81,9 @@ ozi_set_style()
 
     /* set up mkshort */
     if (global_opts.synthesize_shortnames) {
-        setshort_length(32);
-        setshort_whitespace_ok(0);
-        setshort_badchars(xcsv_file.badchars);
+        setshort_length(mkshort_handle, 32);
+        setshort_whitespace_ok(mkshort_handle, 0);
+        setshort_badchars(mkshort_handle, xcsv_file.badchars);
     }
 }
 
@@ -101,6 +104,8 @@ ozi_wr_init(const char *fname, const char *args)
 {
     ozi_set_style();
 
+    mkshort_handle = mkshort_new_handle();
+
     xcsv_file.xcsvfp = fopen(fname, "w");
     
     if (xcsv_file.xcsvfp == NULL) {
index cb81973e448066f458e398bd9db1108805f96d94..e404ad6e7d8a2309a84ec5536fd8f81e0d6d9c1b 100644 (file)
@@ -24,6 +24,7 @@
 
 static FILE *file_in;
 static FILE *file_out;
+static void *mkshort_handle;
 
 #define MYNAME "PCX"
 
@@ -47,6 +48,8 @@ static void
 wr_init(const char *fname, const char *args)
 {
        file_out = fopen(fname, "w");
+       mkshort_handle = mkshort_new_handle();
+
        if (file_out == NULL) {
                fatal(MYNAME ": Cannot open %s for writing\n", fname);
        }
@@ -56,6 +59,7 @@ static void
 wr_deinit(void)
 {
        fclose(file_out);
+       mkshort_del_handle(mkshort_handle);
 }
 
 static void
@@ -118,7 +122,8 @@ gpsutil_disp(const waypoint *wpt)
 
        fprintf(file_out, "W  %-6.6s %c%08.5f %c%011.5f %s %5d %-40.40s %5e  %s\n",
                 global_opts.synthesize_shortnames ?
-                        mkshort(wpt->description) : wpt->shortname,
+                        mkshort(mkshort_handle, wpt->description) : 
+                       wpt->shortname,
                lat < 0.0 ? 'S' : 'N',
                fabs(lat),
                lon < 0.0 ? 'W' : 'E',
@@ -144,7 +149,7 @@ fprintf(file_out,
 "U  LAT LON DM\n"
 "\n"
 "H  IDNT   LATITUDE    LONGITUDE    DATE      TIME     ALT   DESCRIPTION                              PROXIMITY     SYMBOL ;waypts\n");
-       setshort_length(6);
+       setshort_length(mkshort_handle, 6);
        waypt_disp_all(gpsutil_disp);
 }
 
index 3e86092663bbb6076c3f0d77efccc586461b54b1..e23793fb2130a8fe2432250a2e82d7133a0beb50 100644 (file)
@@ -35,6 +35,7 @@
 
 static FILE *psp_file_in;
 static FILE *psp_file_out;
+static FILE *mkshort_handle;
 
 static int i_am_little_endian;
 static int endianness_tested;
@@ -259,6 +260,8 @@ static void
 psp_wr_init(const char *fname, const char *args)
 {
        psp_file_out = fopen(fname, "wb");
+       mkshort_handle = mkshort_new_handle();
+
        if (psp_file_out == NULL) {
                fatal(MYNAME ": Cannot open %s for writing\n", fname);
        }
@@ -267,6 +270,7 @@ psp_wr_init(const char *fname, const char *args)
 static void
 psp_wr_deinit(void)
 {
+       mkshort_del_handle(mkshort_handle);
        fclose(psp_file_out);
 }
 
@@ -404,7 +408,7 @@ psp_waypt_pr(const waypoint *wpt)
         if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
             if (wpt->description) {
                 if (global_opts.synthesize_shortnames)
-                    shortname = mkshort(wpt->description);
+                    shortname = mkshort(mkshort_handle, wpt->description);
                 else
                     shortname = xstrdup(wpt->description);
             } else {
@@ -518,8 +522,8 @@ psp_write(void)
         s = waypt_count();
         
         if (global_opts.synthesize_shortnames) {
-            setshort_length(32);
-            setshort_whitespace_ok(1);
+            setshort_length(mkshort_handle, 32);
+            setshort_whitespace_ok(mkshort_handle, 1);
         }
 
         if (s > MAXPSPOUTPUTPINS) {
index e6b1ca90e744ad361230a17a39367a17d6d788bf..ecf9370a10f6be7073a87dee86bc0e77bfd155c3 100644 (file)
@@ -24,6 +24,7 @@
 
 static FILE *file_in;
 static FILE *file_out;
+static void *mkshort_handle;
 
 #define MYNAME "GPSUTIL"
 
@@ -31,6 +32,8 @@ static void
 rd_init(const char *fname, const char *args)
 {
        file_in = fopen(fname, "r");
+       mkshort_handle = mkshort_new_handle();
+
        if (file_in == NULL) {
                fatal(MYNAME ": Cannot open %s for reading\n", fname);
        }
@@ -40,12 +43,14 @@ static void
 rd_deinit(void)
 {
        fclose(file_in);
+       mkshort_del_handle(mkshort_handle);
 }
 
 static void
 wr_init(const char *fname, const char *args)
 {
        file_out = fopen(fname, "w");
+
        if (file_out == NULL) {
                fatal(MYNAME ": Cannot open %s for writing\n", fname);
        }
@@ -63,18 +68,21 @@ data_read(void)
        double lat,lon;
        char desc[100];
        char icon[100];
+       char ibuf[1024];
        waypoint *wpt_tmp;
 
-       while( fscanf(file_in, "%lf,%lf:%100[^:]:%100[^\n]", 
-                       &lon, &lat, icon, desc) > 0) {
-               wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1);
+       while (fgets(ibuf, sizeof(ibuf), file_in)) {
+               if( sscanf(ibuf, "%lf,%lf:%100[^:]:%100[^\n]", 
+                               &lon, &lat, icon, desc)) {
+                       wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1);
 
-               wpt_tmp->position.longitude.degrees = lon;
-               wpt_tmp->position.latitude.degrees = lat;
-               wpt_tmp->description = xstrdup(desc);
-               wpt_tmp->shortname = mkshort(desc);
+                       wpt_tmp->position.longitude.degrees = lon;
+                       wpt_tmp->position.latitude.degrees = lat;
+                       wpt_tmp->description = xstrdup(desc);
+                       wpt_tmp->shortname = mkshort(mkshort_handle, desc);
 
-               waypt_add(wpt_tmp);
+                       waypt_add(wpt_tmp);
+               }
        }
 }
 
index 1f9dea6758a97aec0d4f1193cc6251ec59d4d20b..529d4f1ea12c3956f5b432fd1e33cd61ac440737 100644 (file)
@@ -40,6 +40,7 @@
 
 static FILE *file_in;
 static FILE *file_out;
+static void *mkshort_handle;
 
 static void 
 rd_init(const char *fname, const char *args)
@@ -185,7 +186,7 @@ tmpro_waypt_pr(const waypoint * wpt)
        if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
         if (wpt->description) {
             if (global_opts.synthesize_shortnames)
-                shortname = mkshort(wpt->description);
+                shortname = mkshort(mkshort_handle, wpt->description);
             else
                 shortname = csv_stringclean(wpt->description, ",\"");
         } else {
@@ -234,15 +235,17 @@ data_write(void)
 {
        /* Short names */
        if (global_opts.synthesize_shortnames) {
-        setshort_length(6);
-        setshort_whitespace_ok(0);
-        setshort_badchars("\",");
+       mkshort_handle = mkshort_new_handle();
+        setshort_length(mkshort_handle, 6);
+        setshort_whitespace_ok(mkshort_handle, 0);
+        setshort_badchars(mkshort_handle, "\",");
     }
     
        /* Write file header */
        fprintf(file_out, "Group\tsID\tsDescription\tfLat\tfLong\tfEasting\tfNorthing\tfAlt\tiColour\tiSymbol\tsHyperLink\n");
 
     waypt_disp_all(tmpro_waypt_pr);
+    mkshort_del_handle(mkshort_handle);
 }
 
 ff_vecs_t tmpro_vecs = {
index ad756ea8ef296551763a4ab482e8788c5b133ec8..8ef169dda00c2ac8649a1c97d33bc574573eb4e9 100644 (file)
@@ -30,6 +30,7 @@
 
 static FILE *tpg_file_in;
 static FILE *tpg_file_out;
+static void *mkshort_handle;
 
 static int i_am_little_endian;
 static int endianness_tested;
@@ -146,6 +147,8 @@ static void
 tpg_wr_init(const char *fname, const char *args)
 {
        tpg_file_out = fopen(fname, "wb");
+       mkshort_handle = mkshort_new_handle();
+
        if (tpg_file_out == NULL) {
                fatal(MYNAME ": Cannot open %s for writing\n", fname);
        }
@@ -266,7 +269,7 @@ tpg_waypt_pr(const waypoint *wpt)
         if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
             if (wpt->description) {
                 if (global_opts.synthesize_shortnames)
-                    shortname = mkshort(wpt->description);
+                    shortname = mkshort(mkshort_handle, wpt->description);
                 else
                     shortname = xstrdup(wpt->description);
             } else {
@@ -351,8 +354,8 @@ tpg_write(void)
         s = waypt_count();
 
         if (global_opts.synthesize_shortnames) {
-            setshort_length(32);
-            setshort_whitespace_ok(1);
+            setshort_length(mkshort_handle, 32);
+            setshort_whitespace_ok(mkshort_handle, 1);
         }
 
         if (s > MAXTPGOUTPUTPINS) {
index 761d17bd2f10fb1c37ca4e04c31956661d50b817..49704b4d5060c0d8607bca9801a1da28b7052d58 100644 (file)
 
 queue waypt_head;
 static unsigned int waypt_ct;
+static void *mkshort_handle;
 
 void
 waypt_init(void)
 {
+       mkshort_handle = mkshort_new_handle();
        QUEUE_INIT(&waypt_head);
 }
 
@@ -66,8 +68,9 @@ waypt_disp(const waypoint *wpt)
        printposn(&wpt->position.longitude,0);
        printf("%s/%s", 
                global_opts.synthesize_shortnames ? 
-                       mkshort(wpt->description) : wpt->shortname, 
-               wpt->description);
+                       mkshort(mkshort_handle, wpt->description) : 
+                               wpt->shortname, 
+                               wpt->description);
        if (wpt->position.altitude.altitude_meters != unknown_alt)
                printf(" %f", wpt->position.altitude.altitude_meters);
        printf("\n");
index b03bb14ddb815c60e411fe046e3c895f2c1bebd1..74b08a25e72b476da3681e6431f96298fc5d6bc4 100644 (file)
@@ -30,6 +30,8 @@
 #define MYNAME "XCSV"
 #define ISSTOKEN(a,b) (strncmp(a,b, strlen(b)) == 0)
 
+static void *mkshort_handle;
+
 /* a table of config file constants mapped to chars */
 static 
 char_map_t xcsv_char_table[] = {
@@ -329,6 +331,7 @@ static void
 xcsv_wr_init(const char *fname, const char *args)
 {
     const char * p;
+    mkshort_handle = mkshort_new_handle();
     
     /* if we don't have an internal style defined, we need to
      * read it from a user-supplied style file, or die trying.
@@ -345,17 +348,17 @@ xcsv_wr_init(const char *fname, const char *args)
         if (global_opts.synthesize_shortnames) {
             p = get_option(args, "snlen");
             if (p)
-                setshort_length(atoi(p));
+                setshort_length(mkshort_handle, atoi(p));
 
             p = get_option(args, "snwhite");
             if (p)
-                setshort_whitespace_ok(atoi(p));
+                setshort_whitespace_ok(mkshort_handle, atoi(p));
 
             p = get_option(args, "snupper");
             if (p)
-                setshort_mustupper(atoi(p));
+                setshort_mustupper(mkshort_handle, atoi(p));
 
-            setshort_badchars(xcsv_file.badchars);
+            setshort_badchars(mkshort_handle, xcsv_file.badchars);
         }
     }
 
index c1e834f79204051d53e2affb4d01d2356ac225a1..fa3da78736c0305e24df7cdf0d34b061d05416c5 100644 (file)
@@ -27,6 +27,7 @@
 #include "csv_util.h"
 
 #define MYNAME "XMAPWPT"
+static void *mkshort_handle;
 
 static void
 xmapwpt_set_style()
@@ -66,9 +67,9 @@ xmapwpt_set_style()
 
     /* set up mkshort */
     if (global_opts.synthesize_shortnames) {
-        setshort_length(32);
-        setshort_whitespace_ok(0);
-        setshort_badchars(xcsv_file.badchars);
+        setshort_length(mkshort_handle, 32);
+        setshort_whitespace_ok(mkshort_handle, 0);
+        setshort_badchars(mkshort_handle, xcsv_file.badchars);
     }
 }
 
@@ -87,6 +88,8 @@ xmapwpt_rd_init(const char *fname, const char *args)
 static void
 xmapwpt_wr_init(const char *fname, const char *args)
 {
+    mkshort_handle = mkshort_new_handle();
+
     xmapwpt_set_style();
 
     xcsv_file.xcsvfp = fopen(fname, "w");